package Visitor;

import Arbori.Nod;
import Functii.Arccos;
import Functii.Arcctg;
import Functii.Arcsin;
import Functii.Arctg;
import Functii.Constanta;
import Functii.Cos;
import Functii.Cosh;
import Functii.Cotangenta;
import Functii.Exponentiala;
import Functii.Logaritm;
import Functii.Necunoscuta;
import Functii.Putere;
import Functii.Radical;
import Functii.Sin;
import Functii.Sinh;
import Functii.Tangenta;
import Operatori.Cat;
import Operatori.Minus;
import Operatori.Plus;
import Operatori.Produs;

public class DerivareVisitor extends Visitor{
	
	String rezultat;
	ToStringVisitor tsv = new ToStringVisitor();

	public DerivareVisitor(String r) {
		//super();
		this.rezultat = r;
	}

	public DerivareVisitor() {
		this.rezultat="";
	}

	public String getrezultatultat() {
		return rezultat;
	}

	public void setrezultatultat(String rezultatultat) {
		this.rezultat = rezultatultat;
	}
	public ToStringVisitor getTsv() {
		return tsv;
	}
	public void setTsv(ToStringVisitor tsv) {
		this.tsv = tsv;
	}
	
	
	public void visit(Plus p) {
		if(p.getFStang() != null && p.getFDrept() != null){
			visit(p.getFStang());
			String s1 = this.rezultat;
			visit(p.getFDrept());
			String s2 = this.rezultat;
			rezultat = p.concatTermeni(s1, s2);
		}
	}

	public void visit(Minus m) {
		if(m.getFStang() != null && m.getFDrept() != null){
			visit(m.getFStang());
			String s1 = this.rezultat;
			visit(m.getFDrept());
			String s2 = this.rezultat;
			rezultat = m.concatTermeni(s1, s2);
		}
	}

	public void visit(Produs p) {
		if(p.getFStang() != null && p.getFDrept() != null){
			visit(p.getFStang());
			String f1d = this.rezultat;
			visit(p.getFDrept());
			String f2d = this.rezultat;
			p.getFStang().acceptVisitor(tsv);
			String f1 = tsv.getS();
			p.getFDrept().acceptVisitor(tsv);
			String f2 = tsv.getS();
			rezultat = Plus.concatTermens(Produs.concatTermens(f1d, f2), Produs.concatTermens(f1, f2d));
		}
	}

	public void visit(Cat c) {
		if(c.getFStang() != null && c.getFDrept() != null){
			visit(c.getFStang());
			String f1d = this.rezultat;
			visit(c.getFDrept());
			String f2d = this.rezultat;
			c.getFStang().acceptVisitor(tsv);
			String f1 = tsv.getS();
			c.getFDrept().acceptVisitor(tsv);
			String f2 = tsv.getS();
			rezultat = Cat.concatTermens(Minus.concatTermens(Produs.concatTermens(f1d, f2), 
					Produs.concatTermens(f1, f2d)), Putere.concatTermens(f2));
		}
	}

	public void visit(Sin s) {
		if(s.getFStang() != null){
			visit(s.getFStang());
			String fsd = this.rezultat;
			s.getFStang().acceptVisitor(tsv);
			String f = tsv.getS();
			rezultat = Produs.concatTermens(Cos.concatTermens(f), fsd);
		}
	}

	public void visit(Cos c) {
		if(c.getFStang() != null){
			visit(c.getFStang());
			String fsd = this.rezultat;
			c.getFStang().acceptVisitor(tsv);
			String f = tsv.getS();
			rezultat = Produs.concatTermens(fsd, Sin.concatTermens(f));
		}
	}

	public void visit(Tangenta t) {
		
	}

	public void visit(Cotangenta c) {
		
	}

	@Override
	public void visit(Arcsin as) {
		
	}

	@Override
	public void visit(Arccos ac) {
		
	}

	@Override
	public void visit(Arctg at) {
		
	}

	@Override
	public void visit(Arcctg ac) {
		
	}

	@Override
	public void visit(Sinh sh) {
		
	}

	@Override
	public void visit(Cosh ch) {
		
	}

	public void visit(Constanta c) {
		rezultat = "0";
	}

	public void visit(Necunoscuta n) {
		rezultat = "1";
	}

	public void visit(Radical r) {
		if(r.getFStang() != null){
			visit(r.getFStang());
			String f = this.rezultat;
			rezultat = Cat.concatTermens("1", Produs.concatTermens("2", Radical.concatTermens(f)));
		}
	}

	public void visit(Putere p) {
		if(p.getFStang() != null){
			visit(p.getFStang());
			String f= this.rezultat;
			rezultat = Produs.concatTermens("2", f);
		}
	}

	@Override
	public void visit(Exponentiala e) {
		
	}

	@Override
	public void visit(Logaritm l) {
		
	}

	@Override
	public void visit(Nod n) {
		
	}
	
	
}
